import dataclasses
import logging
import math
import os
import io
import sys
import time
import json
import re


def _make_w_io_base(f, mode: str):
    if not isinstance(f, io.IOBase):
        f_dirname = os.path.dirname(f)
        if f_dirname != "":
            os.makedirs(f_dirname, exist_ok=True)
        f = open(f, mode=mode)
    return f


def _make_r_io_base(f, mode: str):
    if not isinstance(f, io.IOBase):
        f = open(f, mode=mode)
    return f


def jdump(obj, f, mode="w", indent=4, default=str):
    """Dump a str or dictionary to a file in json format.

    Args:
        obj: An object to be written.
        f: A string path to the location on disk.
        mode: Mode for opening the file.
        indent: Indent for storing json dictionaries.
        default: A function to handle non-serializable entries; defaults to `str`.
    """
    f = _make_w_io_base(f, mode)
    if isinstance(obj, (dict, list)):
        json.dump(obj, f, indent=indent, ensure_ascii=False, default=default)
    elif isinstance(obj, str):
        f.write(obj)
    else:
        raise ValueError(f"Unexpected type: {type(obj)}")
    f.close()


def jload(f, mode="r"):
    """Load a .json file into a dictionary."""
    f = _make_r_io_base(f, mode)
    jdict = json.load(f)
    f.close()
    return jdict


def percent_to_decimal(matchobj):
    percent_val = float(matchobj.group(1)) / 100
    return str(percent_val)


def compute_expression(matchobj):
    expression = matchobj.group(1)
    result = eval(expression.split('=')[0])  # 计算算式的结果
    return ': ' + str(result)


# 输入是两个dict，判断第一个dict中的key和value是否都在第二个dict中，如果是返回True，否则返回False
def is_dict_in_dict(dict1, dict2):
    try:
        for key, value in dict1.items():
            if key not in dict2.keys():
                return False
            # 如果value 是float
            if isinstance(value, float) and value > 1000:
                if abs(value - dict2[key]) > 1:
                    return False
            elif value != dict2[key]:
                return False
    except Exception as e:
        print(e)
        return False

    return True


def json_load_llm_result(output):
    try:
        output_json = json.loads(output)
    except:
        result = output
        if "信息" in result:
            if "未提及" in result or "没有" in result or "未提供" in result or "无法" in result or "无需" in result or "不能" in result:
                output_json = {}
                return output_json
        elif ("{" in result) and ("}" in result):
            if "%" in result:
                result = re.sub(r"(\d+)%", percent_to_decimal, result)
            if "=" in result:
                result = re.sub(r':\s*([\d\+\-\*/\.]+)=([\d\.]+)', compute_expression, result)

        result = str(result).replace("“", "\"").replace("”", "\"")
        result = str(result).replace("：", ":")
        result = str(result).replace("```json", "").replace("```", "")
        result = str(result).replace("\n", "")
        try:
            output_json = json.loads(result)
        except:
            output_json = eval(result)
        # 判断result_eval是否是json
        if not isinstance(output_json, dict):
            return {}
            # raise Exception(result + "：不是json")
    # 去掉output_json中的结果是"未知"或"未提及"或"无"的key
    if isinstance(output_json, dict):
        for key in list(output_json.keys()):
            if "未知" == output_json[key] or "未提及" == output_json[key] or "无" == output_json[key]:
                output_json.pop(key)
    return output_json


if __name__ == "__main__":
    result = json_load_llm_result("""```json
{"x":"y"}
```""")
    print(result)
